#include "stdafx.h"
#include "CppUnitTest.h"

#include <vector>
#include <memory>

#include <HSModel/World.h>
#include <HSModel/WorldDumper.h>
#include <HSModel/FindWaterAreas.h>
#include <HSModel/Water.h>
#include <HSModel/Model3DStorage.h>
#include <HSModel/SharedConstants.h>
#include <HSModel/Ground.h>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace HSModelTests
{
	TEST_CLASS(WorldDumperWaterTests)
	{
	public:
    TEST_METHOD(ShouldRestoreNoWater)
      {
      World world;

      GameController game_ctrl;
      WorldDumper dumper(world, game_ctrl, "DumperTests.xml");
      dumper.Dump();

      World world2;
      WorldDumper dumper2(world2, game_ctrl, "DumperTests.xml");
      dumper2.Restore();

      std::vector<std::shared_ptr<Water>> models_restored = world2.GetGround()->GetWaterModels();

      size_t water_count_expected = 0;
      size_t water_count_actual = models_restored.size();

      Assert::AreEqual(water_count_expected, water_count_actual);
      }

    TEST_METHOD(ShouldRestoreProperCountOfWaterModels)
      {
      World world;

      // Add water to model
      std::vector<std::shared_ptr<Water>> water_objects = HeightMapUtils::GetWaterModels(world.GetGround()->GetHeightMap(), GroundConstants::WATER_LEVEL);
      Assert::IsTrue(water_objects.size() >= 3);
      
      for (size_t i = 0; i < 3; ++i)
        world.GetGround()->AddWaterModel(water_objects[i]);

      GameController game_ctrl;
      WorldDumper dumper(world, game_ctrl, "DumperTests.xml");
      dumper.Dump();

      World world2;
      WorldDumper dumper2(world2, game_ctrl, "DumperTests.xml");
      dumper2.Restore();

      std::vector<std::shared_ptr<Water>> models_restored = world2.GetGround()->GetWaterModels();
      
      size_t water_count_expected = 3;
      size_t water_count_actual = models_restored.size();

      Assert::AreEqual(water_count_expected, water_count_actual);
      }

    TEST_METHOD(ShouldRestoreProperWaterModel)
      {
      World world;

      // Add water to model
      std::vector<std::shared_ptr<Water>> water_objects = HeightMapUtils::GetWaterModels(world.GetGround()->GetHeightMap(), GroundConstants::WATER_LEVEL);
      Assert::IsFalse(water_objects.empty());
      world.GetGround()->AddWaterModel(water_objects[0]);

      THMapArea water_info_expected = water_objects[0]->GetArea();
      size_t point_count_expected = water_info_expected.points.size();

      GameController game_ctrl;
      WorldDumper dumper(world, game_ctrl, "DumperTests.xml");
      dumper.Dump();

      World world2;
      WorldDumper dumper2(world2, game_ctrl, "DumperTests.xml");
      dumper2.Restore();

      std::vector<std::shared_ptr<Water>> models_restored = world2.GetGround()->GetWaterModels();

      size_t water_count_expected = 1;
      size_t water_count_actual = models_restored.size();
      Assert::AreEqual(water_count_expected, water_count_actual);

      THMapArea water_info_actual = models_restored[0]->GetArea();
      Assert::AreEqual(water_info_expected.level, water_info_actual.level);
      size_t point_count_actual = water_info_actual.points.size();
      
      Assert::AreEqual(point_count_expected, point_count_actual);

      }

	};
}